package com.ycnet.springapp.web.config;

import java.util.EnumSet;

import javax.servlet.DispatcherType;
import javax.servlet.FilterRegistration;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletRegistration;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.security.config.BeanIds;
import org.springframework.web.WebApplicationInitializer;
import org.springframework.web.context.ContextLoaderListener;
import org.springframework.web.context.support.AnnotationConfigWebApplicationContext;
import org.springframework.web.filter.CharacterEncodingFilter;
import org.springframework.web.filter.DelegatingFilterProxy;
import org.springframework.web.servlet.DispatcherServlet;

import com.ycnet.springapp.config.AppConfig;

/**
 * 用于替代web.xml的web容器配置类 在这里配置过滤器、监听器、Servlet
 *
 * @author ycnet
 *
 */
public class RangerWebApplicationInitializer implements WebApplicationInitializer {
	private static final Logger logger = LoggerFactory.getLogger(RangerWebApplicationInitializer.class);

	@Override
	public void onStartup(ServletContext servletContext) throws ServletException {

		logger.info("in YcnetWebApplicationInitializer");
		// 顺序无关
		// 1.配置spring容器refresh前的回调类
		callbackMethodBeforeSpringRefreshed(servletContext);

		// 2.配置基于注解的Spring容器上下文
		configSpringRootContext(servletContext);

		// 3.配置基于注解的Web容器上下文
		configSpringMvcContext(servletContext);

		// 4.配置Spring提供的字符编码过滤器
		configCharacterEncodingFilter(servletContext);

		// 5.配置springSecurity Filter
		configSpringSecurityFilter(servletContext);

	}

	private void configSpringSecurityFilter(ServletContext servletContext) {
		FilterRegistration.Dynamic springSecurityFilterChain = servletContext.addFilter(BeanIds.SPRING_SECURITY_FILTER_CHAIN, new DelegatingFilterProxy());
		springSecurityFilterChain.addMappingForUrlPatterns(null, false, "/*");
	}

	private void configSpringMvcContext(ServletContext servletContext) {
		AnnotationConfigWebApplicationContext springMvcContext = new AnnotationConfigWebApplicationContext();
		// 注册Web容器配置类
		springMvcContext.register(WebMvcConfig.class);
		ServletRegistration.Dynamic dispatcher = servletContext.addServlet("dispatcher", new DispatcherServlet(springMvcContext));
		// 配置映射路径
		dispatcher.addMapping("/app/*");
		// 启动顺序
		dispatcher.setLoadOnStartup(1);
	}

	private void configSpringRootContext(ServletContext servletContext) {
		AnnotationConfigWebApplicationContext rootContext = new AnnotationConfigWebApplicationContext();
		// 注册Spring容器配置类
		rootContext.register(AppConfig.class);
		servletContext.addListener(new ContextLoaderListener(rootContext));
	}

	private void configCharacterEncodingFilter(ServletContext servletContext) {
		FilterRegistration.Dynamic filter = servletContext.addFilter("encoding", new CharacterEncodingFilter("uft-8"));
		// 配置过滤器的过滤路径
		filter.addMappingForUrlPatterns(EnumSet.of(DispatcherType.REQUEST), true, "/");

	}

	private void callbackMethodBeforeSpringRefreshed(ServletContext servletContext) {
		servletContext.setInitParameter("contextInitializerClasses", "com.ycnet.springapp.web.config.WebContextInitializerClasse");
	}

}